<template>
  <p>App</p>
  <p>{{ count }}</p>
  <p>{{ oddOrEven }}</p>
  <button @click="count++">按钮</button>

  <p>{{ person.age }}</p>
  <button @click="updateAge">按钮</button>
</template>

<script lang="ts">
import { ref, reactive, watch, computed, watchEffect } from "vue";

export default {
  name: "App",
  // 组合式API入口，所有组合式API的内容都必须写在这个函数中
  // setup初始化渲染就会触发，相当于（取缔） beforeCreate 和 created
  setup() {
    const count = ref(0);

    watch(
      count,
      (newVal, oldVal) => {
        console.log(newVal, oldVal);
      },
      { immediate: true, deep: true }
    );

    const person = reactive({
      age: 18,
    });

    // 如果监视reactive数据，监视整体直接写
    watch(person, (newVal, oldVal) => {
      console.log(newVal, oldVal);
    });

    // 如果监视reactive数据中某个属性，必须写成函数形式
    watch(
      () => person.age,
      (newVal, oldVal) => {
        console.log(newVal, oldVal);
      }
    );

    // 可以监视多个属性
    watch([count, person], (newVal, oldVal) => {
      console.log("监视多个属性", newVal, oldVal);
    });

    // 只读计算属性
    const oddOrEven = computed(() => {
      return count.value % 2 === 1 ? "奇数" : "偶数";
    });

    // 可读可写计算属性
    // const xxx = computed({
    //   get() {},
    //   set(newVal) {}
    // });

    const updateAge = () => {
      person.age++;
      count.value++;
    };

    // 一旦内部引用的响应式数据发送变化，就会重新执行函数
    // 函数初始化渲染就会执行一次
    watchEffect(
      () => {
        console.log("watchEffect", count.value, person.age);
      },
      {
        flush: "pre", // DOM更新之前触发（默认值）
        // flush: 'post', // DOM更新之后触发
        // flush: "sync", // DOM更新之前触发, 数据更新后立即执行
      }
    );

    return {
      count,
      person,
      updateAge,
      oddOrEven,
    };
  },
};
</script>
